local skynet = require "skynet"
local socket = require "skynet.socket"

package.path = package.path .. ';/home/ubuntu/IMDT_GameDev/?.lua';
require "src.GameRoleMgr"
require "src.util"

-- 初始化用户
local roleMgr = GameRoleMgr.new()
roleMgr:generate_role_list(10000)

local port = 8960
local ip = "43.136.68.19"
local ip = "0.0.0.0"

-- 与客户端约定的指令表,key为前缀（的正则搜索表达式，-前需要%转义符）,value为要执行的方法
local commands = {}

-- 协议工具函数
-- 服务器返回字符串，以|为分割，第一段为状态码，1成功0失败，后面为返回内容
local function send(id, code, content)
    local code = tostring(code)
    local res = code .. "|" .. content
    socket.write(id, res)
end

-- 配置指令
-- 登录
commands['system%-login|'] = function(id, pams)
    local roleId = tonumber(pams[1])
    local role = roleMgr:get_rol_by_id(roleId)
    if type(role) == 'string' then
        -- 登录失败，发回原因
        print(role)
        send(id, 0, role)
    else
        -- 登录成功，发回role信息
        print(role)
        send(id, 1, role.name)
    end
end

-- 删除角色
commands['player%-delete%-role|'] = function(id, pams)
    local roleId = tonumber(pams[1])
    local res = roleMgr:del_rol_by_id(roleId)
    if type(res) == 'string' then
        -- 登录失败，发回原因
        print(res)
        send(id, 0, res)
    else
        -- 登录成功，发回role信息
        print(res)
        send(id, 1, res:__tostring())
    end
end

-- 按攻击力排序查询角色
commands['player%-request%-roles%-atk|'] = function(id, pams)
    local num = tonumber(pams[1])
    local res = roleMgr:get_att_sort_list(num)
    if type(res) == 'string' then
        -- 登录失败，发回原因
        print(res)
        send(id, 0, res)
    else
        -- 登录成功，得到一个数组
        print(res)
        send(id, 1, tonumber(#res) .. "\n")
        for i, v in ipairs(res) do
            send(id, 1, res[i]:__tostring() .. "\n")
            if i % 50 == 0 then skynet.sleep(50) end
        end
    end
end

local function exec_message(strin, id)
    -- 逐个对照指令表执行
    for k, v in pairs(commands) do
        local head, tail = string.find(strin, k)
        if tail then
            -- 成功匹配
            local pams = string.sub(strin, tail + 1)
            -- 切割参数
            pams = string_split(pams, "|")
            -- 执行对应函数
            v(id, pams)
        end
    end
end

-- 接收到客户端连接或收到客户端消息
local function handle_client(id, addr)
    print("connect from " .. addr .. " " .. id)
    skynet.error("handle_client service", coroutine.running())
    -- 任何一个服务只有在调用 socket.start(id) 之后，才可以收到这个 socket 上的数据。
    socket.start(id)

    while true do
        local str = socket.read(id)
        if str then
            print("client say:" .. str)
            exec_message(str, id)
            -- 把一个字符串置入正常的写队列，skynet 框架会在 socket 可写时发送它。
            -- socket.write(id, str)
        else
            print("handle_client-- over")
            socket.close(id)
            return
        end
    end
end

-- 启动服务器
local function start_server()
    print("==========Socket Start=========")
    -- 监听一个端口，返回一个 id ，供 start 使用。
    local srv_id = socket.listen(ip, port)
    print("Listen socket :", ip, port)

    socket.start(srv_id, handle_client)
end

-- 启动服务器
skynet.start(start_server)
